home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
pcl_src.zoo
/
init.lsp
< prev
next >
Wrap
Lisp/Scheme
|
1992-07-09
|
14KB
|
325 lines
;;;-*-Mode:LISP; Package:(PCL LISP 1000); Base:10; Syntax:Common-lisp -*-
;;;
;;; *************************************************************************
;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
;;; All rights reserved.
;;;
;;; Use and copying of this software and preparation of derivative works
;;; based upon this software are permitted. Any distribution of this
;;; software or derivative works must comply with all applicable United
;;; States export control laws.
;;;
;;; This software is made available AS IS, and Xerox Corporation makes no
;;; warranty about the software, its performance or its conformity to any
;;; specification.
;;;
;;; Any person obtaining a copy of this software is requested to send their
;;; name and post office or electronic mail address to:
;;; CommonLoops Coordinator
;;; Xerox PARC
;;; 3333 Coyote Hill Rd.
;;; Palo Alto, CA 94304
;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa)
;;;
;;; Suggestions, comments and requests for improvements are also welcome.
;;; *************************************************************************
;;;
;;;
;;; This file defines the initialization and related protocols.
;;;
(in-package 'pcl)
(declaim (type boolean *check-initargs-p*))
(defvar *check-initargs-p* nil)
(defmacro checking-initargs (&body forms)
`(when *check-initargs-p* ,@forms))
(declaim (type boolean *making-instance-p*))
(defvar *making-instance-p* nil)
(defmethod make-instance ((class slot-class) &rest initargs)
(declare (list initargs))
(unless (class-finalized-p class) (finalize-inheritance class))
(let ((class-default-initargs (class-default-initargs class)))
(when class-default-initargs
(setf initargs (default-initargs class initargs class-default-initargs)))
(when initargs
(when (and (eq *boot-state* 'complete)
(not (getf initargs :allow-other-keys)))
(let ((class-proto (class-prototype class)))
(check-initargs-1
class initargs
(append (compute-applicable-methods
#'allocate-instance (list* class initargs))
(compute-applicable-methods
#'initialize-instance (list* class-proto initargs))
(compute-applicable-methods
#'shared-initialize (list* class-proto t initargs)))))))
(let* ((*making-instance-p* T)
(instance (apply #'allocate-instance class initargs)))
(apply #'initialize-instance instance initargs)
instance)))
(defmethod make-instance ((class-name symbol) &rest initargs)
(apply #'make-instance (find-class class-name) initargs))
(defvar *default-initargs-flag* (list nil))
(defmethod default-initargs ((class slot-class) supplied-initargs all-default)
;; This implementation of default initargs is critically dependent
;; on all-default-initargs not having any duplicate initargs in it.
(let ((miss *default-initargs-flag*))
(flet ((getf* (plist key)
(do ()
((null plist) miss)
(if (eq (car plist) key)
(return (cadr plist))
(setq plist (cddr plist))))))
(labels ((default-1 (tail)
(if (null tail)
nil
(if (eq (getf* supplied-initargs (caar tail)) miss)
(list* (caar tail)
(funcall-function (cadar tail))
(default-1 (cdr tail)))
(default-1 (cdr tail))))))
(append supplied-initargs (default-1 all-default))))))
(defmethod allocate-instance ((class standard-class) &rest initargs)
(declare (ignore initargs))
(unless (or *making-instance-p* (class-finalized-p class))
(finalize-inheritance class))
(let* ((class-wrapper (class-wrapper class))
(instance (%allocate-instance--class
(wrapper-allocate-static-slot-storage-copy
class-wrapper))))
(setf (std-instance-wrapper instance) class-wrapper)
instance))
(defmethod allocate-instance ((class structure-class) &rest initargs)
(declare (ignore initargs))
(let ((constructor (class-defstruct-constructor class)))
(if constructor
(funcall-function (symbol-function constructor))
(error "Can't allocate an instance of class ~S" (class-name class)))))
(defmethod initialize-instance ((instance slot-object) &rest initargs)
(apply #'shared-initialize instance t initargs))
(defmethod reinitialize-instance ((instance slot-object) &rest initargs)
(checking-initargs
(when (and initargs (eq *boot-state* 'complete)
(not (getf initargs :allow-other-keys)))
(check-initargs-1
(class-of instance) initargs
(append (compute-applicable-methods
#'reinitialize-instance (list* instance initargs))
(compute-applicable-methods
#'shared-initialize (list* instance nil initargs))))))
(apply #'shared-initialize instance nil initargs)
instance)
(defmethod update-instance-for-different-class ((previous standard-object)
(current standard-object)
&rest initargs)
;; First we must compute the newly added slots. The spec defines
;; newly added slots as "those local slots for which no slot of
;; the same name exists in the previous class."
(let ((added-slots '())
(current-slotds (class-slots (class-of current)))
(previous-slot-names (mapcar #'slot-definition-name
(class-slots (class-of previous)))))
(dolist (slotd current-slotds)
(if (and (not (memq (slot-definition-name slotd) previous-slot-names))
(eq (slot-definition-allocation slotd) ':instance))
(push (slot-definition-name slotd) added-slots)))
(checking-initargs
(when (and initargs (not (getf initargs :allow-other-keys)))
(check-initargs-1
(class-of current) initargs
(append (compute-applicable-methods
#'update-instance-for-different-class
(list* previous current initargs))
(compute-applicable-methods
#'shared-initialize (list* current added-slots initargs))))))
(apply #'shared-initialize current added-slots initargs)))
(defmethod update-instance-for-redefined-class ((instance standard-object)
added-slots
discarded-slots
property-list
&rest initargs)
(checking-initargs
(when (and initargs (not (getf initargs :allow-other-keys)))
(check-initargs-1
(class-of instance) initargs
(append (compute-applicable-methods
#'update-instance-for-redefined-class
(list* instance added-slots discarded-slots property-list initargs))
(compute-applicable-methods
#'shared-initialize (list instance added-slots initargs))))))
(apply #'shared-initialize instance added-slots initargs))
(defmethod shared-initialize
((instance slot-object) slot-names &rest initargs)
(declare (list initargs))
(declare #.*optimize-speed*)
;;
;; initialize the instance's slots in a two step process
;; 1. A slot for which one of the initargs in initargs can set
;; the slot, should be set by that initarg. If more than
;; one initarg in initargs can set the slot, the leftmost
;; one should set it.
;;
;; 2. Any slot not set by step 1, may be set from its initform
;; by step 2. Only those slots specified by the slot-names
;; argument are set. If slot-names is:
;; T
;; any slot not set in step 1 is set from its
;; initform
;; <list of slot names>
;; any slot in the list, and not set in step 1
;; is set from its initform
;;
;; ()
;; no slots are set from initforms
;;
(flet
((init-safe (slots initing-internal-slotds)
(dolist (internal-slotd initing-internal-slotds)
(unless
(and
initargs
;; Try to initialize the slot from one of the initargs.
(let ((slot-initargs (internal-slotd-initargs internal-slotd))
(initargs-ptr initargs))
(loop
(when (memq (car initargs-ptr) slot-initargs)
(let ((location (internal-slotd-location internal-slotd)))
(typec